package proyecto0.src;

import java.io.File;
import java.io.FileNotFoundException;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Scanner;

/**
* @author Martin E. Castro & Gabriel I. Paez - Tecnologia de Programacion 2014
*/

public class Principal {
    
    protected HashMap <String,Integer> checkings;
    protected int cant;
    
    /**
     * Crea un mapeo vacio y setea la cantidad de palabras leidas en cero.
     */
    public Principal(){
        checkings=new HashMap<String,Integer>();
        cant=0;
    }

    /**
     * Metodo para agregar las palabras de todos los archivos de un directorio
     * en un mapeo con clave de tipo String y valor de tipo Integer. Con el
     * mapeo se agrupara cada palabra con la cantidad de apariciones en total
     * @param directory Directorio al que se desea acceder a chequear los archivos
     */
	public void loadMap(String directory){
        File dir = new File(directory);
        if(dir.exists()){
            File[] files = dir.listFiles();
            for (File f : files) 
            	loadFileInMap(f);             
        }
    }
	
	/**
	 * Metodo para cargar las palabras de un archivo en el mapeo, quitandole a lo sumo a cada una un signo especial al comienzo y/o final de dicha palabra
	 * ACLARACION: los signos contemplados en este ejercicio para ser validos son mayusculas, minusculas o letras especiales (letras con tildes, con dierecis, cedillas...). 
	 * @param f Archivo para acceder a mapear las palabras
	 */
	private void loadFileInMap(File f){
		if(f.isFile() && f.getPath().endsWith("txt")) {
		Scanner sc=null; 
        try{
           	sc=new Scanner(f);
           	//Mientras haya lineas para leer en el archivo...
           	while(sc.hasNextLine()){ 
             	//Creo un Scanner con una linea del archivo en cada ciclo while
               	Scanner sc2=new Scanner(sc.nextLine().toLowerCase());
               	//Mientras la linea del Scanner tenga palabras para leer.
               	while(sc2.hasNext()){
               		//Paso la palabra a minusculas y chequeo si esta o no en el mapeo
                   	String s=sc2.next();
    	            //Tomo el primer caracter para chequear que comience con una letra y obtengo el codigo ASCII del mismo
    	          	char characterStart = s.charAt(0); 
    	          	int asciiBegining = (int) characterStart;
    	          	//Tomo el ultimo caracter para chequear que comience con una letra y obtengo el codigo ASCII del mismo
                	char characterEnd = s.charAt(s.length()-1); 
   	              	int asciiEnding = (int) characterEnd;
   	              	//Si la palabra comienza con algun signo distinto a cualquier letra minuscula, lo elimino
   	              	if(!((97<=asciiBegining && asciiBegining<=122)||(65<=asciiBegining && asciiBegining<=90)||(147<asciiBegining && asciiBegining<152)||(asciiBegining!=198)))
   	              		s=s.substring(1,s.length());
   	              	//Si la palabra finaliza con algun signo distinto a cualquier letra minuscula, lo elimino
   	              	if(!(97<=asciiEnding && asciiEnding<=122)&& !(65<=asciiEnding && asciiEnding<=90)&& !(147<=asciiEnding && asciiEnding<=152)&&(asciiEnding!=198))                		
   	              		s=s.substring(0,s.length()-1);
   	              	if(!checkings.containsKey(s)) 
   		            	checkings.put(s,1);
   		            else{
   		            	int newValue=checkings.get(s)+1;
   		            	checkings.put(s, newValue);
   		            }
   		           	cant++;
               	}
               	sc2.close();
           	}
           	if(checkings.containsKey(""))
           		checkings.remove("");
        }
            catch(FileNotFoundException e){
            	e.printStackTrace();
            }
            
        }
	}
    
    /**
     * Crea y retorna un mapeo con las cinco palabras mas repetidas del directorio y el porcentaje de apariciones de cada una.
     * @return Mapeo con las cinco palabras mas repetidas de los archivos del directorio con sus respectivos porcentajes de apariciones.
     */
	public HashMap<String,String> fiveMostFound(){
        HashMap<String,String> retornar=new HashMap<String,String>();
        if(!checkings.isEmpty()){
            int i=0;
            while(i<=4 && !checkings.isEmpty()){
                Iterator<Entry<String,Integer>> it=checkings.entrySet().iterator();
                Entry<String,Integer> toSave = null;
                if(it.hasNext())
                        toSave=it.next();
                while(it.hasNext()){
                    Entry<String,Integer>actual=it.next();
                    if(actual.getValue()>toSave.getValue())
                        toSave=actual;                          
                }
                String g=porcentaje(toSave.getValue());
                retornar.put(toSave.getKey(),g+"%");
                checkings.remove(toSave.getKey());
                i++;
            }
        }   
        return retornar;
    }
	
	/**
	 * Metodo que retorna un string conteniendo el porcentaje que representa la cantidad de apariciones de una palabra
	 * @param valor cantidad de veces que aparece una palabra
	 * @return Porcentaje que representa la cantidad de apariciones de una palabra.
	 */
	private String porcentaje(int valor){
		NumberFormat nf= NumberFormat.getInstance();
		nf.setMaximumFractionDigits(2);
		nf.setGroupingUsed(false);
		Double perc= (double)(valor*100.00)/cant;
		return nf.format(perc);
	}
}